#!/usr/bin/env python
# -*- coding: utf-8 -*-

from flask import Blueprint, request, jsonify, g, send_file
from datetime import datetime
from app.models import ActivationCode, Agent, ActivationCodeBatch, User
from app.core.extensions import db
from sqlalchemy import func, desc
import datetime
import uuid
import random
from io import BytesIO
import pandas as pd
from flask_jwt_extended import jwt_required

# 创建蓝图
activation_codes_bp = Blueprint('admin_activation_codes', __name__)


@activation_codes_bp.route('/activation-codes', methods=['GET'])
def get_activation_codes():
    """小程序专用：获取激活码列表（无JWT验证）"""
    try:
        # 获取查询参数
        per_page = int(request.args.get('per_page', 20))
        status = request.args.get('status', type=int)
        is_copied = request.args.get('is_copied', type=int)
        is_exported = request.args.get('is_exported', type=int)
        agent_id = request.args.get('agent_id', type=int)
        expire_days = request.args.get('expire_days', type=int)
        usage_count = request.args.get('usage_count', type=int)

        # 构建查询
        query = ActivationCode.query

        if status is not None:
            query = query.filter_by(status=status)

        if usage_count is not None:
            query = query.filter_by(usage_count=usage_count)

        if is_copied is not None:
            query = query.filter_by(is_copied=bool(is_copied))

        if is_exported is not None:
            query = query.filter_by(is_exported=bool(is_exported))

        if agent_id is not None:
            query = query.filter_by(created_by=agent_id)

        if expire_days is not None:
            if expire_days == 0:
                query = query.filter(ActivationCode.expire_time.is_(None))
            else:
                query = query.filter(ActivationCode.expire_days == expire_days)

        # 直接获取最多per_page条数据
        items = query.limit(per_page).all()
        total = len(items)  # 简化计算，总数就是返回的数量

        return jsonify({
            "code": 0,
            "message": "获取成功",
            "data": {
                "items": [code_to_dict(code) for code in items],
                "page": 1,
                "per_page": per_page,
                "total": total
            }
        })
    except Exception as e:
        print(f"获取激活码列表失败: {str(e)}")
        return jsonify({"code": -1, "message": f"获取激活码列表失败: {str(e)}"}), 500


@activation_codes_bp.route('/get-codes-data', methods=['GET'])
def get_codes():
    """小程序专用：获取激活码列表（无JWT验证）"""
    try:
        # 获取查询参数
        status = request.args.get('status', type=int)
        is_copied = request.args.get('is_copied', type=int)
        is_exported = request.args.get('is_exported', type=int)
        agent_id = request.args.get('agent_id', type=int)
        usage_count = request.args.get('usage_count', type=int)

        # 构建查询
        query = ActivationCode.query

        if status is not None:
            query = query.filter_by(status=status)

        if usage_count is not None:
            query = query.filter_by(usage_count=usage_count)

        if is_copied is not None:
            query = query.filter_by(is_copied=bool(is_copied))

        if is_exported is not None:
            query = query.filter_by(is_exported=bool(is_exported))

        if agent_id is not None:
            query = query.filter_by(created_by=agent_id)

        # 直接获取最多per_page条数据
        items = query.all()
        total = len(items)  # 简化计算，总数就是返回的数量

        return jsonify({
            "code": 0,
            "message": "获取成功",
            "data": {
                "items": [code_to_dict(code) for code in items],
                "total": total
            }
        })
    except Exception as e:
        print(f"获取激活码列表失败: {str(e)}")
        return jsonify({"code": -1, "message": f"获取激活码列表失败: {str(e)}"}), 500


@activation_codes_bp.route('/query-code', methods=['GET'])
def query_codes():
    """小程序专用：获取激活码信息（无JWT验证）"""
    try:
        # 获取查询参数
        code_num = request.args.get('codeNum', type=int)

        if not code_num:
            return jsonify({"code": 1, "message": "请提供激活码编号"}), 200

        # 查询激活码
        code = ActivationCode.query.filter_by(code=code_num).first()

        if not code:
            return jsonify({"code": 1, "message": "未找到对应的激活码"}), 200

        # 查询用户信息（如果已使用）
        user = None
        if code.used_by:
            user = User.query.filter_by(user_id=code.used_by).first()

        return jsonify({
            "code": 0,
            "message": "获取成功",
            "data": {
                "code": {
                    "code": code.code,
                    "totalCount": code.usage_count,
                    "status": code.status,
                    "used_by": code.used_by,
                    "used_at": code.used_time.strftime('%Y-%m-%d %H:%M:%S') if code.used_time else None
                },
                "user": {
                    "id": user.user_id,
                    "nickname": user.nick_name,
                    "remainingCount": user.usage_count if user else 0,
                } if user else None
            }
        })

    except Exception as e:
        print(f"获取激活码信息失败: {str(e)}")
        return jsonify({"code": -1, "message": f"获取激活码信息失败: {str(e)}"}), 500


@activation_codes_bp.route('/export-codes-data', methods=['GET'])
def export_codes():
    """小程序专用：获取激活码列表（无JWT验证）"""
    try:

        # 获取查询参数
        status = request.args.get('status', type=int)
        is_copied = request.args.get('is_copied', type=int)
        is_exported = request.args.get('is_exported', type=int)
        agent_id = request.args.get('agent_id', type=int)
        usage_count = request.args.get('usage_count', type=int)
        limit = request.args.get('limit', 100, type=int)

        if limit > 200:
            limit = 200
        if not agent_id:
            return jsonify({
                'code': 1,
                'message': '请提供代理ID'
            }), 400

        # 构建查询 - 先验证代理和租户
        agent = Agent.query.get(agent_id)
        if not agent:
            return jsonify({
                'code': 1,
                'message': '代理不存在'
            }), 400

        if not agent.tenant_id:
            return jsonify({
                'code': 1,
                'message': '代理没有关联租户'
            }), 400

        # 构建WHERE条件
        where_conditions = [f"tenant_id = {agent.tenant_id}", f"created_by = {agent_id}"]

        if status is not None:
            where_conditions.append(f"status = {status}")
        if usage_count is not None:
            where_conditions.append(f"usage_count = {usage_count}")
        if is_copied is not None:
            where_conditions.append(f"is_copied = {1 if is_copied else 0}")
        if is_exported is not None:
            where_conditions.append(f"is_exported = {1 if is_exported else 0}")

        where_clause = " AND ".join(where_conditions)

        from sqlalchemy import text
        # 执行数据查询（使用text包装原生SQL）
        data_sql = f"SELECT * FROM activation_codes WHERE {where_clause} LIMIT {limit}"
        data_result = db.session.execute(text(data_sql))
        raw_codes = data_result.mappings().all()

        codes = []
        for row in raw_codes:
            code = ActivationCode()
            for column, value in row.items():
                setattr(code, column, value)
            codes.append(code)

        code_ids = [code.id for code in codes]
        if code_ids:
            ActivationCode.query.filter(ActivationCode.id.in_(code_ids)).update(
                {"is_exported": True}, synchronize_session=False
            )
            db.session.commit()
        else:
            print("⚠️ 未获取到有效 code.id，跳过 update")

        # 提交数据库变更
        db.session.commit()
        # 构建 Excel
        data = [code_to_dict(c) for c in codes]

        # ✅ 你想导出的字段 + 中文标题
        export_fields = {
            "code": "激活码",
            "usage_count": "次数",
            "status": "状态",
            "is_copied": "是否复制",
            "is_exported": "是否导出",
            "create_time": "创建时间",
        }

        # ✅ 构建导出数据
        processed_data = []
        for item in data:
            new_row = {}
            for field, zh_label in export_fields.items():
                value = item.get(field, '')
                if value == 0:
                    new_row[zh_label] = '否'
                elif value == 1:
                    new_row[zh_label] = '是'
                else:
                    new_row[zh_label] = value
            processed_data.append(new_row)
        df = pd.DataFrame(processed_data)
        output = BytesIO()
        with pd.ExcelWriter(output, engine='xlsxwriter') as writer:
            df.to_excel(writer, index=False, sheet_name='激活码列表')

        output.seek(0)

        return send_file(
            output,
            download_name='activation_codes.xlsx',
            as_attachment=True,
            mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        )

    except Exception as e:
        print(f"获取激活码列表失败: {str(e)}")
        return jsonify({"code": -1, "message": f"获取激活码列表失败: {str(e)}"}), 500


@activation_codes_bp.route('/activation-codes/statistics', methods=['GET'])
def get_activation_codes_statistics():
    """小程序专用：获取激活码统计信息（无JWT验证）"""
    try:
        agent_id = request.args.get('agent_id', type=int)

        # 构建基础查询
        query = ActivationCode.query

        # 如果指定了代理ID，只查询该代理的激活码
        if agent_id:
            query = query.filter(ActivationCode.created_by == agent_id)

        # 获取各状态数量
        total_count = query.count()
        unused_count = query.filter(ActivationCode.status == 0).count()
        used_count = query.filter(ActivationCode.status == 1).count()
        copied_count = query.filter(ActivationCode.is_copied == True).count()
        exported_count = query.filter(ActivationCode.is_exported == True).count()

        return jsonify({
            'code': 0,
            'message': '获取成功',
            'data': {
                'total_count': total_count,
                'unused_count': unused_count,
                'used_count': used_count,
                'copied_count': copied_count,
                'exported_count': exported_count
            }
        })
    except Exception as e:
        print(f"获取统计信息失败: {str(e)}")
        return jsonify({"code": -1, "message": f"获取统计信息失败: {str(e)}"}), 500


@activation_codes_bp.route('/activation-codes/mark-copied/<int:code_id>', methods=['POST'])
def mark_activation_code_copied(code_id):
    """小程序专用：标记激活码为已复制（无JWT验证）"""
    try:
        code = ActivationCode.query.get_or_404(code_id)

        code.is_copied = True
        code.copied_time = datetime.datetime.now()

        db.session.commit()

        return jsonify({
            'code': 0,
            'message': '标记成功',
            'data': {
                'copied_time': code.copied_time.strftime('%Y-%m-%d %H:%M:%S') if code.copied_time else None
            }
        })
    except Exception as e:
        print(f"标记为已复制失败: {str(e)}")
        return jsonify({"code": -1, "message": f"操作失败: {str(e)}"}), 500


@activation_codes_bp.route('/activation-codes/mark-exported/<int:code_id>', methods=['POST'])
def mark_activation_code_exported(code_id):
    """小程序专用：标记激活码为已导出（无JWT验证）"""
    try:
        code = ActivationCode.query.get_or_404(code_id)

        code.is_exported = True
        code.exported_time = datetime.datetime.now()

        db.session.commit()

        return jsonify({
            'code': 0,
            'message': '标记成功',
            'data': {
                'exported_time': code.exported_time.strftime('%Y-%m-%d %H:%M:%S') if code.exported_time else None
            }
        })
    except Exception as e:
        print(f"标记为已导出失败: {str(e)}")
        return jsonify({"code": -1, "message": f"操作失败: {str(e)}"}), 500


@activation_codes_bp.route('/activation-codes/batch-mark-copied', methods=['POST'])
def batch_mark_activation_codes_copied():
    """小程序专用：批量标记激活码为已复制（无JWT验证）"""
    try:
        data = request.json
        code_ids = data.get('code_ids', [])

        if not code_ids:
            return jsonify({
                'code': 1,
                'message': '请选择要标记的激活码'
            }), 400

        codes = ActivationCode.query.filter(ActivationCode.id.in_(code_ids)).all()
        current_time = datetime.datetime.now()

        for code in codes:
            code.is_copied = True
            code.copied_time = current_time

        db.session.commit()

        return jsonify({
            'code': 0,
            'message': f'成功标记{len(codes)}个激活码为已复制',
            'data': {
                'affected_count': len(codes)
            }
        })
    except Exception as e:
        print(f"批量标记为已复制失败: {str(e)}")
        return jsonify({"code": -1, "message": f"操作失败: {str(e)}"}), 500


@activation_codes_bp.route('/activation-codes/batch-mark-exported', methods=['POST'])
def batch_mark_activation_codes_exported():
    """小程序专用：批量标记激活码为已导出（无JWT验证）"""
    try:
        data = request.json
        code_ids = data.get('code_ids', [])

        if not code_ids:
            return jsonify({
                'code': 1,
                'message': '请选择要标记的激活码'
            }), 400

        codes = ActivationCode.query.filter(ActivationCode.id.in_(code_ids)).all()
        current_time = datetime.datetime.now()

        for code in codes:
            code.is_exported = True
            code.exported_time = current_time

        db.session.commit()

        return jsonify({
            'code': 0,
            'message': f'成功标记{len(codes)}个激活码为已导出',
            'data': {
                'affected_count': len(codes)
            }
        })
    except Exception as e:
        print(f"批量标记为已导出失败: {str(e)}")
        return jsonify({"code": -1, "message": f"操作失败: {str(e)}"}), 500


# 生成唯一激活码函数
def generate_unique_code(prefix='045', length=8):
    """
    生成唯一的激活码
    """
    # 获取所有存在的激活码
    existing_codes = set([code.code for code in ActivationCode.query.all()])

    # 生成不重复的激活码
    while True:
        # 生成指定长度的随机数字
        min_val = 10 ** (length - 1)
        max_val = (10 ** length) - 1
        random_number = random.randint(min_val, max_val)

        # 组合成完整激活码
        code_str = f"{prefix}{random_number}"

        # 确保不重复
        if code_str not in existing_codes:
            return code_str


@activation_codes_bp.route('/activation-codes/generate', methods=['POST'])
def generate_activation_codes():
    """小程序专用：生成激活码（无JWT验证）"""
    try:
        data = request.json

        count = data.get('count', 1)
        agent_id = data.get('agent_id')
        usage_count = data.get('usage_count', 1)  # 获取使用次数参数
        expire_days = data.get('expire_days', 0)

        if count <= 0 or count > 1000:
            return jsonify({"code": -1, "message": "生成数量应在1-1000之间"}), 400

        if not agent_id:
            return jsonify({"code": -1, "message": "代理ID不能为空"}), 400

        # 查询代理信息，确认代理存在
        agent = Agent.query.get(agent_id)
        if not agent:
            return jsonify({"code": -1, "message": "代理不存在"}), 404

        # 计算需要扣除的总次数
        total_usage = count * usage_count

        # 检查代理剩余可生成次数是否足够
        remaining_count = agent.max_generation_count - agent.used_generation_count
        if remaining_count < total_usage:
            return jsonify(
                {"code": -1, "message": f"剩余可生成次数不足，当前剩余: {remaining_count}，需要: {total_usage}"}), 400

        # 创建激活码批次
        batch_id = str(uuid.uuid4()).replace('-', '')[:16]
        current_time = datetime.datetime.now()

        # 创建批次记录
        batch = ActivationCodeBatch(
            id=batch_id,
            agent_id=agent_id,
            count=count,
            usage_count=usage_count,
            expire_days=expire_days
        )
        db.session.add(batch)

        # 计算过期时间
        expire_time = None
        if expire_days > 0:
            expire_time = current_time + datetime.timedelta(days=expire_days)

        # 生成激活码
        codes = []

        for _ in range(count):
            # 使用通用函数生成唯一激活码
            code_str = generate_unique_code(prefix='045', length=11)

            # 创建激活码对象
            code = ActivationCode(
                code=code_str,
                usage_count=usage_count,  # 设置使用次数
                status=0,
                is_copied=False,
                is_exported=False,
                created_by=agent_id,
                create_time=current_time,
                expire_time=expire_time,
                batch_id=batch_id
            )

            db.session.add(code)
            codes.append(code)

        # 更新代理已使用的生成次数
        agent.used_generation_count = agent.used_generation_count + total_usage

        db.session.commit()

        return jsonify({
            'code': 0,
            'message': f'成功生成{count}个激活码',
            'data': {
                'count': count,
                'codes': [code_to_dict(code) for code in codes[:10]],  # 只返回前10个
                'agent': {
                    'remaining_count': agent.max_generation_count - agent.used_generation_count,
                    'used_count': agent.used_generation_count,
                    'max_count': agent.max_generation_count
                }
            }
        })
    except Exception as e:
        db.session.rollback()
        print(f"生成激活码失败: {str(e)}")
        return jsonify({"code": -1, "message": f"生成失败: {str(e)}"}), 500

@activation_codes_bp.route('/activation-codes/web-key', methods=['POST'])
def web_activation_codes():
    """小程序专用：生成激活码（无JWT验证）"""
    try:
        data = request.json
        count = data.get('count', 1)
        agent_id = data.get('agent_id',1)
        usage_count = 300 # 获取使用次数参数
        expire_days = data.get('expire_days', 0)

        if count <= 0 or count > 1000:
            return jsonify({"code": -1, "message": "生成数量应在1-1000之间"}), 400

        if not agent_id:
            return jsonify({"code": -1, "message": "代理ID不能为空"}), 400

        # 查询代理信息，确认代理存在
        agent = Agent.query.get(agent_id)
        if not agent:
            return jsonify({"code": -1, "message": "代理不存在"}), 404

        # 计算需要扣除的总次数
        total_usage = count * usage_count

        # 检查代理剩余可生成次数是否足够
        remaining_count = agent.max_generation_count - agent.used_generation_count
        if remaining_count < total_usage:
            return jsonify(
                {"code": -1, "message": f"剩余可生成次数不足，当前剩余: {remaining_count}，需要: {total_usage}"}), 400

        # 创建激活码批次
        batch_id = str(uuid.uuid4()).replace('-', '')[:16]
        current_time = datetime.datetime.now()

        # 创建批次记录
        batch = ActivationCodeBatch(
            id=batch_id,
            agent_id=agent_id,
            count=count,
            usage_count=usage_count,
            expire_days=expire_days
        )
        db.session.add(batch)

        # 计算过期时间
        expire_time = None
        if expire_days > 0:
            expire_time = current_time + datetime.timedelta(days=expire_days)

        # 生成激活码
        codes = []

        for _ in range(count):
            # 使用通用函数生成唯一激活码
            code_str = generate_unique_code(prefix='045', length=11)

            # 创建激活码对象
            code = ActivationCode(
                code=code_str,
                usage_count=usage_count,  # 设置使用次数
                status=0,
                is_copied=False,
                is_exported=False,
                created_by=agent_id,
                create_time=current_time,
                expire_time=expire_time,
                batch_id=batch_id
            )

            db.session.add(code)
            codes.append(code)

        # 更新代理已使用的生成次数
        agent.used_generation_count = agent.used_generation_count + total_usage

        db.session.commit()

        return jsonify({
            'code': 0,
            'message': f'成功生成{count}个激活码',
            'data': {
                'count': count,
                'codes': [code_to_dict(code) for code in codes[:10]],  # 只返回前10个
                'agent': {
                    'remaining_count': agent.max_generation_count - agent.used_generation_count,
                    'used_count': agent.used_generation_count,
                    'max_count': agent.max_generation_count
                }
            }
        })
    except Exception as e:
        db.session.rollback()
        print(f"生成激活码失败: {str(e)}")
        return jsonify({"code": -1, "message": f"生成失败: {str(e)}"}), 500

def code_to_dict(code):
    """将激活码对象转换为字典"""
    result = {
        'id': code.id,
        'code': code.code,
        'status': code.status,
        'usage_count': code.usage_count,
        'is_copied': code.is_copied,
        'is_exported': code.is_exported,
        'created_by': code.created_by,
        'create_time': code.create_time.strftime('%Y-%m-%d %H:%M:%S') if code.create_time else None,
        'used_by': code.used_by,
        'used_time': code.used_time.strftime('%Y-%m-%d %H:%M:%S') if code.used_time else None,
        'expire_time': code.expire_time.strftime('%Y-%m-%d %H:%M:%S') if code.expire_time else None,
        'batch_id': code.batch_id,
        'copied_time': code.copied_time.strftime('%Y-%m-%d %H:%M:%S') if code.copied_time else None,
        'exported_time': code.exported_time.strftime('%Y-%m-%d %H:%M:%S') if code.exported_time else None
    }

    return result


# 注册蓝图
def init_app(app):
    app.register_blueprint(activation_codes_bp, url_prefix='/api/admin/mp')
